#require 'singleton'

class Cart

  #include Singleton

  attr_accessor :items, :expires_at, :ordered, :kvn_branch, :client_id, :saved_cart

  def initialize(client_id)
    @items = Array.new
    @expires_at = 1.day.from_now
    @ordered = false
    @client_id = client_id

    load_saved_items
  end

  def add_items(items)
    items.each do |item|
      add_item(item)
    end
  end

  def add_item(item)
    # If item's combination of product_id and color_id doesn't exist,
    # it will be added to the "items" array. If it does, the item will
    # be updated with the new quantity.

    index = find_item(item)

    if index.blank?
      @items << item
      SavedCart.add_item(@client_id, item)
    else
      update_existing_item(index, item.quantity)
      SavedCart.update_item(@client_id, item)
    end

    self
  end

  def remove_item(item_id)
    item = @items.find{ |i| i.item_id == item_id }
    @items.delete(item)
    SavedCart.remove_item(@client_id, item)

    self
  end

  def items
    @items
  end

  def empty
    @items = Array.new
    SavedCart.empty_cart(@client_id)
  end

  def total_amount
    total = 0

    @items.each do |item|
      product = Product.find(item.product_id)
      subtotal = product.get_price(@kvn_branch) * item.quantity
      total = total + subtotal
    end

    total
  end

  def mark_as_ordered
    @ordered = true
  end

  def active?
    @expires_at > Time.now && !self.ordered?
  end

  def ordered?
    @ordered == true
  end

  def get_item(item_id)
    @items.find { |i| i.item_id == item_id }
  end

  private

  def find_item(item)
    @items.find_index { |i| i.product_id == item.product_id and i.color_id == item.color_id }
  end

  def update_existing_item(index, quantity)
    # Adds quantity to existing Cart Item
    @items[index].quantity = @items[index].quantity + quantity
  end

  def load_saved_items
    saved_items = SavedCart.where(:client_id => @client_id)

    unless saved_items.blank?
      saved_items.each do |si|
        item = CartItem.new(si.product_id.to_i, si.product_color_id, si.quantity.to_i)

        product = Product.unscoped.find(si.product_id)

        if product.available?
          @items << item
        else
          SavedCart.remove_item(@client_id, item)
        end
      end
    end
  end
end